home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / DJGPP / BNU22SR1.ZIP / src / binutils.2 / bfd / doc / chew.c < prev    next >
C/C++ Source or Header  |  1993-05-30  |  23KB  |  1,364 lines

  1. /* chew
  2.    Copyright (C) 1990-1991 Free Software Foundation, Inc.
  3.    Contributed by steve chamberlain @cygnus
  4.  
  5. This file is part of BFD, the Binary File Descriptor library.
  6.  
  7. This program is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with this program; if not, write to the Free Software
  19. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /*
  22.  Yet another way of extracting documentation from source.
  23.  No, I haven't finished it yet, but I hope you people like it better
  24.  that the old way
  25.   
  26.  sac
  27.  
  28. Basically, this is a sort of string forth, maybe we should call it
  29. struth?
  30.  
  31. You define new words thus:
  32. : <newword> <oldwords> ;
  33. There is  no
  34.  
  35. */
  36.  
  37.  
  38.  
  39. #include <ansidecl.h>
  40. #include "sysdep.h"
  41.  
  42. #define DEF_SIZE 5000
  43. #define STACK 50
  44.  
  45. int internal_wanted;
  46. int internal_mode;
  47.  
  48. int warning;
  49.  
  50.  
  51. /* Here is a string type ... */
  52.  
  53. typedef struct buffer 
  54. {
  55.     char *ptr;
  56.     unsigned int write_idx;
  57.     unsigned int size;
  58. } string_type;
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.  
  66. static void DEFUN(init_string_with_size,(buffer, size),
  67.        string_type *buffer AND
  68.        unsigned int size )
  69. {
  70.     buffer->write_idx = 0;
  71.     buffer->size = size;
  72.     buffer->ptr = malloc(size);
  73. }
  74.  
  75. static void DEFUN(init_string,(buffer),
  76.        string_type *buffer)
  77. {
  78.     init_string_with_size(buffer, DEF_SIZE);
  79.  
  80. }
  81.  
  82. static int DEFUN(find, (str, what),
  83.       string_type *str AND
  84.       char *what)
  85. {
  86.     unsigned int i;
  87.     char *p;
  88.     p = what;
  89.     for (i = 0; i < str->write_idx && *p; i++) 
  90.     {
  91.     if (*p == str->ptr[i])
  92.      p++;
  93.     else
  94.      p = what;
  95.     }
  96.     return (*p == 0);
  97.     
  98. }
  99.  
  100. static void DEFUN(write_buffer,(buffer),
  101.        string_type *buffer)
  102. {
  103.     fwrite(buffer->ptr, buffer->write_idx, 1, stdout);
  104. }
  105.  
  106.  
  107. static void DEFUN(delete_string,(buffer),
  108.        string_type *buffer)
  109. {
  110.     free(buffer->ptr);
  111. }
  112.  
  113.  
  114. static char *DEFUN(addr, (buffer, idx),
  115.         string_type *buffer AND
  116.         unsigned int idx)
  117. {
  118.     return buffer->ptr + idx;
  119. }
  120.  
  121. static char DEFUN(at,(buffer, pos),
  122.        string_type *buffer AND
  123.        unsigned int pos) 
  124. {
  125.     if ( pos >= buffer->write_idx) 
  126.     {
  127.     return 0;
  128.     }
  129.     return buffer->ptr[pos];
  130. }
  131.  
  132. static void DEFUN(catchar,(buffer, ch), 
  133.        string_type *buffer AND
  134.        char ch)
  135. {
  136.     if (buffer->write_idx == buffer->size) 
  137.     {
  138.     buffer->size *=2;
  139.     buffer->ptr = realloc(buffer->ptr, buffer->size);
  140.     }
  141.  
  142.     buffer->ptr[buffer->write_idx ++ ] = ch;
  143. }
  144.  
  145.  
  146. static void DEFUN(overwrite_string,(dst,   src),
  147.        string_type *dst AND
  148.        string_type *src)
  149. {
  150.     free(dst->ptr);
  151.     dst->size = src->size;
  152.     dst->write_idx = src->write_idx;
  153.     dst->ptr = src->ptr;
  154. }
  155.  
  156. static void DEFUN(catstr,(dst, src),
  157.        string_type *dst AND
  158.        string_type *src)
  159. {
  160.     unsigned int i;
  161.     for (i = 0; i < src->write_idx; i++) 
  162.     {
  163.     catchar(dst, src->ptr[i]);
  164.     }
  165. }
  166.  
  167.  
  168. static void DEFUN(cattext,(buffer, string),
  169.        string_type *buffer AND
  170.        char *string)
  171. {
  172.     
  173.     while (*string) 
  174.     {
  175.     catchar(buffer, *string);
  176.     string++;
  177.     }
  178. }
  179.  
  180. static void DEFUN(catbuf,(buffer, buf, len),
  181.        string_type *buffer AND
  182.        char *buf AND
  183.        unsigned int len)
  184. {
  185.     
  186.     while (len--) 
  187.     {
  188.     catchar(buffer, *buf);
  189.     buf++;
  190.     }
  191. }
  192.  
  193.  
  194.  
  195. static unsigned int 
  196. DEFUN(skip_white_and_stars,(src, idx),
  197.       string_type *src AND
  198.       unsigned int idx)
  199. {
  200.     while (isspace(at(src,idx)) 
  201.        || (at(src,idx) == '*' && at(src,idx +1) !='/'
  202.            && at(src,idx -1) != '\n')) 
  203.      idx++;
  204.     return idx;
  205.     
  206.  
  207. }
  208. /***********************************************************************/
  209.  
  210.  
  211. string_type stack[STACK];
  212. string_type *tos;
  213.  
  214. unsigned int idx = 0; /* Pos in input buffer */
  215. string_type *ptr; /* and the buffer */
  216. typedef void (*stinst_type)();
  217. stinst_type *pc;
  218. stinst_type sstack[STACK];
  219. stinst_type *ssp = &sstack[0];
  220. int istack[STACK];
  221. int *isp = &istack[0];
  222.  
  223. typedef int *word_type;
  224.  
  225.  
  226.  
  227. struct dict_struct
  228. {
  229.     char *word;
  230.     struct dict_struct *next;
  231.    stinst_type *code;
  232.     int code_length;
  233.     int code_end;
  234.     int var;
  235.     
  236. };
  237. typedef struct dict_struct dict_type;
  238. #define WORD(x) static void x()
  239.  
  240. static void DEFUN(exec,(word),
  241.           dict_type *word)
  242. {
  243.     pc = word->code;
  244.     while (*pc) 
  245.     {
  246.     (*pc)();
  247.     }
  248.     
  249. }
  250. WORD(call)
  251. {
  252. stinst_type *oldpc = pc;
  253.     dict_type *e;
  254.     e =  (dict_type *)(pc [1]);
  255.     exec(e);
  256.     pc = oldpc + 2;
  257.     
  258. }
  259.  
  260. WORD(remchar)
  261. {
  262.     tos->write_idx--;    
  263.     pc++;
  264.     
  265. }
  266.  
  267. WORD(push_number)
  268. {
  269.     isp++;
  270.     pc++;
  271.     *isp = (int)(*pc);
  272.     pc++;
  273.     
  274. }
  275.  
  276.  
  277.  
  278.  
  279. WORD(push_text)
  280. {
  281.     
  282.     tos++;
  283.     init_string(tos);
  284.     pc++;
  285.     cattext(tos,*((char **)pc));
  286.     pc++;
  287.     
  288. }
  289.  
  290.  
  291.    
  292. /* This function removes everything not inside comments starting on
  293.    the first char of the line from the  string, also when copying
  294.    comments, removes blank space and leading *'s 
  295.    Blank lines are turned into one blank line
  296.  */
  297.  
  298. static void 
  299. DEFUN(remove_noncomments,(src,dst),
  300.        string_type *src AND
  301.        string_type *dst)
  302. {
  303.     unsigned int idx = 0;
  304.     
  305.     while (at(src,idx)) 
  306.     {
  307.     /* Now see if we have a comment at the start of the line */
  308.     if (at(src,idx) == '\n' 
  309.         && at(src,idx+1) ==  '/' 
  310.         && at(src,idx+2) == '*') 
  311.     {
  312.         idx+=3;
  313.         
  314.         idx = skip_white_and_stars(src,idx);
  315.  
  316.         /* Remove leading dot */
  317.         if (at(src, idx) == '.')
  318.          idx++;
  319.         
  320.         /* Copy to the end of the line, or till the end of the
  321.            comment */
  322.         while (at(src, idx))
  323.         {
  324.         if (at(src, idx) == '\n') 
  325.         {
  326.             /* end of line, echo and scrape of leading blanks  */
  327.             if (at(src,idx +1) == '\n')
  328.              catchar(dst,'\n');
  329.             catchar(dst,'\n');
  330.             idx++;
  331.             idx =   skip_white_and_stars(src, idx);
  332.         }
  333.         else if (at(src, idx) == '*' && at(src,idx+1) == '/') 
  334.         {
  335.             idx +=2 ;
  336.             cattext(dst,"\nENDDD\n");
  337.             break;
  338.         }
  339.         else 
  340.         {
  341.             catchar(dst, at(src, idx));
  342.             idx++;
  343.         }
  344.         }
  345.     }
  346.     else idx++;
  347.     }
  348. }
  349.  
  350. /* turn:
  351.      foobar name(stuff);
  352.    into:
  353.      foobar
  354.      name PARAMS ((stuff));
  355.    and a blank line.
  356.  */
  357.  
  358. static void
  359. DEFUN_VOID(paramstuff)
  360. {
  361.     unsigned int openp;
  362.     unsigned int fname;
  363.     unsigned int idx;
  364.     string_type out;
  365.     init_string(&out);
  366.     
  367.  
  368.     /* make sure that it's not already param'd or proto'd */
  369.     if(find(tos,"PARAMS") || find(tos,"PROTO") || !find(tos,"(")) {
  370.         catstr(&out,tos);
  371.     }
  372.     else 
  373.     {
  374.     /* Find the open paren */
  375.     for (openp = 0; at(tos, openp) != '('  && at(tos,openp); openp++)
  376.      ;
  377.  
  378.     fname = openp;
  379.     /* Step back to the fname */
  380.     fname--;
  381.     while (fname && isspace(at(tos, fname)))
  382.      fname --;
  383.     while (fname && !isspace(at(tos,fname)) && at(tos,fname) != '*')
  384.      fname--;
  385.  
  386.     fname++;
  387.     
  388.     for (idx = 0; idx < fname; idx++)     /* Output type */
  389.     {
  390.         catchar(&out, at(tos,idx));
  391.     }
  392.     
  393.         cattext(&out, "\n");    /* Insert a newline between type and fnname */
  394.  
  395.     for (idx = fname; idx < openp; idx++)         /* Output fnname */
  396.     {
  397.         catchar(&out, at(tos,idx));
  398.     }
  399.  
  400.     cattext(&out," PARAMS (");
  401.  
  402.     while (at(tos,idx) && at(tos,idx) !=';') 
  403.     {
  404.         catchar(&out, at(tos, idx));
  405.         idx++;
  406.     }
  407.     cattext(&out,");\n\n");
  408.     }
  409.     overwrite_string(tos, &out);    
  410.     pc++;
  411.     
  412. }
  413.  
  414.  
  415.  
  416. /* turn {*
  417.    and *} into comments */
  418.  
  419. WORD(translatecomments)
  420. {
  421.     unsigned int idx = 0;
  422.     string_type out;
  423.     init_string(&out);
  424.     
  425.     while (at(tos, idx)) 
  426.     {
  427.     if (at(tos,idx) == '{' && at(tos,idx+1) =='*') 
  428.     {
  429.         cattext(&out,"    /*");
  430.         idx+=2;
  431.     }
  432.     else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  433.     {
  434.         cattext(&out,"*/");
  435.         idx+=2;
  436.     }
  437.     else  
  438.     {
  439.         catchar(&out, at(tos, idx));
  440.         idx++;
  441.     }
  442.     }
  443.  
  444.  
  445.     overwrite_string(tos, &out);
  446.     
  447.     pc++;
  448.     
  449. }
  450.  
  451. /* turn everything not starting with a . into a comment */
  452.  
  453. WORD(manglecomments)
  454. {
  455.     unsigned int idx = 0;
  456.     string_type out;
  457.     init_string(&out);
  458.     
  459.     while (at(tos, idx)) 
  460.     {
  461.     if (at(tos,idx) == '\n' && at(tos,idx+1) =='*') 
  462.     {
  463.         cattext(&out,"    /*");
  464.         idx+=2;
  465.     }
  466.     else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  467.     {
  468.         cattext(&out,"*/");
  469.         idx+=2;
  470.     }
  471.     else  
  472.     {
  473.         catchar(&out, at(tos, idx));
  474.         idx++;
  475.     }
  476.     }
  477.  
  478.  
  479.     overwrite_string(tos, &out);
  480.     
  481.     pc++;
  482.     
  483. }
  484.  
  485. /* Mod tos so that only lines with leading dots remain */
  486. static void
  487. DEFUN_VOID(outputdots)
  488. {
  489.     unsigned int idx = 0;
  490.     string_type out;
  491.     init_string(&out);
  492.     
  493.     while (at(tos, idx)) 
  494.     {
  495.     if (at(tos, idx) == '\n' && at(tos, idx+1) == '.') 
  496.     {
  497.         idx += 2;
  498.         
  499.         while (at(tos, idx) && at(tos, idx)!='\n')
  500.         {
  501.         if (at(tos,idx) == '{' && at(tos,idx+1) =='*') 
  502.         {
  503.             cattext(&out," /*");
  504.             idx+=2;
  505.         }
  506.         else if (at(tos,idx) == '*' && at(tos,idx+1) =='}') 
  507.         {
  508.             cattext(&out,"*/");
  509.             idx+=2;
  510.         }
  511.         else  
  512.         {
  513.             catchar(&out, at(tos, idx));
  514.             idx++;
  515.         }
  516.         }
  517.         catchar(&out,'\n');
  518.     }
  519.     else 
  520.     {
  521.         idx++;
  522.     }
  523.     }    
  524.  
  525.     overwrite_string(tos, &out);
  526.     pc++;
  527.     
  528. }
  529.  
  530. /* Find lines starting with . and | and put example around them on tos */
  531. WORD(courierize)
  532. {
  533.     string_type out;
  534.     unsigned int idx = 0;
  535.     int command = 0;
  536.     
  537.     init_string(&out);
  538.     
  539.     while (at(tos, idx)) 
  540.     {
  541.     if (at(tos, idx) == '\n' 
  542.         && (at(tos, idx +1 ) == '.'
  543.         || at(tos,idx+1) == '|')) 
  544.     {
  545.         cattext(&out,"\n@example\n");
  546.         do 
  547.         {
  548.         idx += 2;
  549.         
  550.         while (at(tos, idx) && at(tos, idx)!='\n')
  551.         {
  552.             if (at(tos,idx)=='{' && at(tos,idx+1) =='*') 
  553.             {
  554.             cattext(&out," /*");
  555.             idx+=2;
  556.             }
  557.             else if (at(tos,idx)=='*' && at(tos,idx+1) =='}') 
  558.             {
  559.             cattext(&out,"*/");
  560.             idx+=2;
  561.             }
  562.                 else if (at(tos,idx) == '{' && !command)
  563.             {
  564.             cattext(&out,"@{");
  565.             idx++;
  566.             }
  567.                 else if (at(tos,idx) == '}' && !command)
  568.             {
  569.             cattext(&out,"@}");
  570.             idx++;
  571.             }
  572.             else 
  573.             {
  574.             if (at(tos,idx) == '@')
  575.                 command = 1;
  576.             else if (isspace(at(tos,idx)) || at(tos,idx) == '}')
  577.                 command = 0;
  578.             catchar(&out, at(tos, idx));
  579.             idx++;
  580.             }
  581.             
  582.         }
  583.         catchar(&out,'\n');
  584.         }  
  585.         while (at(tos, idx) == '\n' 
  586.            && (at(tos, idx+1) == '.')
  587.            || (at(tos,idx+1) == '|'));
  588.         cattext(&out,"@end example");
  589.     }
  590.     else 
  591.     {    
  592.         catchar(&out, at(tos, idx));
  593.         idx++;
  594.     }
  595.     }    
  596.  
  597.     overwrite_string(tos, &out);
  598.     pc++;
  599.  
  600.     
  601. }
  602.  
  603. /* Finds any lines starting with "o ", if there are any, then turns
  604.    on @itemize @bullet, and @items each of them. Then ends with @end
  605.    itemize, inplace at TOS*/
  606.  
  607.  
  608. WORD(bulletize)
  609. {
  610.     unsigned int idx = 0;
  611.     int on = 0;
  612.     string_type out;
  613.     init_string(&out);
  614.     
  615.     while (at(tos, idx)) {
  616.     if (at(tos, idx) == '@' &&
  617.         at(tos, idx+1) == '*') 
  618.     {
  619.       cattext(&out,"*");
  620.       idx+=2;
  621.     }
  622.     
  623. else
  624.         if (at(tos, idx) == '\n' &&
  625.         at(tos, idx+1) == 'o' &&
  626.         isspace(at(tos, idx +2)))
  627.         {
  628.         if (!on) 
  629.         {
  630.             cattext(&out,"\n@itemize @bullet\n");
  631.             on = 1;
  632.             
  633.         }
  634.         cattext(&out,"\n@item\n");
  635.         idx+=3;
  636.         }
  637.         else 
  638.         {
  639.         catchar(&out, at(tos, idx));
  640.         if (on && at(tos, idx) == '\n' &&
  641.             at(tos, idx+1) == '\n' &&
  642.             at(tos, idx+2) != 'o')
  643.         {
  644.             cattext(&out, "@end itemize");
  645.             on = 0;
  646.         }
  647.         idx++;
  648.         
  649.         }
  650.     }
  651.     if (on) 
  652.     {
  653.     cattext(&out,"@end itemize\n");
  654.     }    
  655.  
  656.     delete_string(tos);
  657.     *tos = out;
  658.     pc++;
  659.     
  660. }
  661.  
  662. /* Turn <<foo>> into @code{foo} in place at TOS*/
  663.    
  664.  
  665. WORD(do_fancy_stuff)
  666. {
  667.     unsigned int idx = 0;
  668.     string_type out;
  669.     init_string(&out);
  670.     while (at(tos, idx)) 
  671.     {
  672.     if (at(tos, idx) == '<' 
  673.         && at(tos, idx+1) == '<'
  674.         && !isspace(at(tos,idx + 2))) 
  675.     {
  676.         /* This qualifies as a << startup */
  677.         idx +=2;
  678.         cattext(&out,"@code{");
  679.         while(at(tos,idx) &&
  680.           at(tos,idx) != '>' )
  681.         {
  682.         catchar(&out, at(tos, idx));
  683.         idx++;
  684.         
  685.         }
  686.         cattext(&out,"}");
  687.         idx+=2;
  688.     }
  689.     else 
  690.     {
  691.         catchar(&out, at(tos, idx));
  692.         idx++;
  693.     }
  694.     }
  695.     delete_string(tos);
  696.     *tos = out;
  697.     pc++;
  698.     
  699. }
  700. /* A command is all upper case,and alone on a line */
  701. static int 
  702. DEFUN( iscommand,(ptr, idx),
  703.       string_type *ptr AND
  704.       unsigned int idx)
  705. {
  706.     unsigned int len = 0;
  707.     while (at(ptr,idx)) {
  708.         if (isupper(at(ptr,idx)) || at(ptr,idx) == ' ' ||
  709.         at(ptr,idx) == '_') 
  710.         {
  711.          len++;
  712.          idx++;
  713.      }
  714.         else if(at(ptr,idx) == '\n')
  715.         {
  716.         if (len >4) return 1;
  717.         return 0;
  718.         }
  719.         else return 0;
  720.     }
  721.     return 0;
  722.  
  723. }
  724.  
  725.  
  726. DEFUN(copy_past_newline,(ptr, idx, dst),
  727.       string_type *ptr AND
  728.       unsigned int idx AND
  729.       string_type *dst)
  730. {
  731.     while (at(ptr, idx) && at(ptr, idx) != '\n') 
  732.     {
  733.     catchar(dst, at(ptr, idx));
  734.     idx++;
  735.     
  736.     }    
  737.     catchar(dst, at(ptr, idx));
  738.     idx++;
  739.     return idx;
  740.  
  741. }
  742.  
  743. WORD(icopy_past_newline)
  744. {
  745.     tos++;
  746.     init_string(tos);
  747.     idx = copy_past_newline(ptr, idx, tos);
  748.     pc++;    
  749. }
  750.  
  751. /* indent
  752.    Take the string at the top of the stack, do some prettying */
  753.  
  754.  
  755.  
  756.  
  757. WORD(kill_bogus_lines)
  758. {
  759.     int sl ;
  760.     
  761.     int nl = 0;
  762.     int idx = 0;
  763.     int c;
  764.     int dot = 0    ;
  765.     
  766.     string_type out;    
  767.     init_string(&out);
  768.     /* Drop leading nl */
  769.     while (at(tos,idx) == '\n')
  770.     {
  771.     idx++;
  772.     }
  773.     c = idx;
  774.     
  775.     /* Find the last char */
  776.     while (at(tos,idx))
  777.     {
  778.     idx++;
  779.     }
  780.     
  781.     /* find the last non white before the nl */
  782.     idx--;
  783.     
  784.     while (idx && isspace(at(tos,idx)))
  785.      idx--;
  786.     idx++;
  787.     
  788.     /* Copy buffer upto last char, but blank lines before and after
  789.        dots don't count */
  790.     sl = 1;
  791.  
  792.     while (c < idx)
  793.     {
  794.     if (at(tos,c) == '\n' 
  795.         && at(tos,c+1) == '\n'
  796.         && at(tos,c+2) == '.') 
  797.     {
  798.         /* Ignore two newlines before a dot*/
  799.         c++;
  800.     }
  801.     else if (at(tos,c) == '.' && sl)
  802.     {
  803.         /* remember that this line started with a dot */
  804.         dot=2;
  805.     }
  806.     else if (at(tos,c) == '\n' 
  807.          && at(tos,c+1) == '\n'
  808.          && dot)
  809.     {
  810.         c++;
  811.         /* Ignore two newlines when last line was dot */
  812.     }
  813.  
  814.     catchar(&out, at(tos,c));
  815.     if (at(tos,c) == '\n')
  816.     {
  817.         sl = 1;
  818.         
  819.         if (dot == 2)dot=1;else dot = 0;
  820.     }
  821.     
  822.     c++;    
  823.  
  824.     }
  825.     
  826.     /* Append nl*/
  827.     catchar(&out, '\n');
  828.     pc++;
  829.     delete_string(tos);
  830.     *tos = out;
  831.     
  832.     
  833. }
  834.  
  835. WORD(indent)
  836. {
  837.     string_type out;
  838.     int tab = 0;
  839.     int idx = 0;
  840.     int ol =0;
  841.     init_string(&out);
  842.     while (at(tos,idx)) {
  843.         switch (at(tos,idx)) 
  844.         {
  845.           case '\n':
  846.         cattext(&out,"\n");
  847.         idx++;
  848.         if (tab) 
  849.         {
  850.             cattext(&out,"    ");
  851.         }
  852.         ol = 0;
  853.         break;
  854.           case '(':
  855.         tab++;
  856.         if (ol == 0)
  857.             cattext(&out,"   ");
  858.         idx++;
  859.         cattext(&out,"(");
  860.         ol = 1;
  861.         break;
  862.           case ')':
  863.         tab--;
  864.         cattext(&out,")");
  865.         idx++;
  866.         ol=1;
  867.         
  868.         break;
  869.           default:
  870.         catchar(&out,at(tos,idx));
  871.         ol=1;
  872.         
  873.         idx++;
  874.         break;
  875.         }
  876.     }    
  877.  
  878.     pc++;
  879.     delete_string(tos);
  880.     *tos = out;
  881.  
  882. }
  883.  
  884.  
  885. WORD(get_stuff_in_command)
  886. {
  887.     tos++;
  888.     init_string(tos);
  889.  
  890.     while (at(ptr, idx)) {
  891.         if (iscommand(ptr, idx))  break;
  892.         idx =   copy_past_newline(ptr, idx, tos);
  893.     }
  894. pc++;    
  895. }
  896.  
  897. WORD(swap)
  898. {
  899.     string_type t;
  900.     
  901.     t = tos[0];
  902.     tos[0] = tos[-1];
  903.     tos[-1] =t; 
  904.     pc++;
  905.     
  906. }
  907.  
  908. WORD(other_dup)
  909. {
  910.     tos++;
  911.     init_string(tos);
  912.     catstr(tos, tos-1);
  913.     pc++;
  914.     
  915. }
  916.  
  917.  
  918.  
  919. WORD(icatstr)
  920. {
  921.     catstr(tos-1, tos);
  922.     delete_string(tos);
  923.     tos--;
  924.     pc++;
  925.     
  926. }
  927.  
  928. WORD(skip_past_newline)
  929. {
  930.     while (at(ptr,idx) 
  931.        && at(ptr,idx) != '\n')
  932.      idx++;
  933.     idx++;
  934.     pc++;
  935. }
  936.  
  937.  
  938. WORD(internalmode)
  939. {
  940.     internal_mode = *(isp);
  941.     isp--;
  942.     pc++;
  943. }
  944.  
  945. WORD(maybecatstr)
  946. {
  947.     if (internal_wanted == internal_mode) 
  948.     {
  949.     catstr(tos-1, tos);
  950.     }
  951.     delete_string(tos);
  952.     tos--;
  953.     pc++;
  954.     
  955. }
  956.  
  957. char *
  958. DEFUN(nextword,(string, word),
  959.       char *string AND
  960.       char **word)
  961. {
  962.     char *word_start;
  963.     int idx;
  964.     char *dst;
  965.     char *src;
  966.     
  967.     int length = 0;
  968.     
  969.     while (isspace(*string) || *string == '-') {
  970.         if (*string == '-') 
  971.         {
  972.         while (*string && *string != '\n') 
  973.          string++;
  974.         
  975.         }
  976.         else {
  977.             string++;
  978.         }
  979.     }
  980.     if (!*string) return 0;
  981.     
  982.     word_start = string;        
  983.     if (*string == '"') 
  984.     {
  985.     string++;
  986.     length++;
  987.     
  988.     while (*string != '"') 
  989.     {
  990.         string++;
  991.         length++;
  992.     }
  993.     }
  994.     else     
  995.     {
  996.     
  997.  
  998.     while (!isspace(*string)) 
  999.     {
  1000.         string++;
  1001.         length++;
  1002.     
  1003.     }
  1004.     }
  1005.     
  1006.     *word = malloc(length + 1);
  1007.  
  1008.     dst = *word;
  1009.     src = word_start;
  1010.  
  1011.  
  1012.     for (idx= 0; idx < length; idx++) 
  1013.     {
  1014.     
  1015.     if (src[idx] == '\\' && src[idx+1] == 'n') 
  1016.     {
  1017.         *dst++ = '\n';
  1018.         idx++;
  1019.     
  1020.     }
  1021.     else *dst++ = src[idx];
  1022.     }
  1023.     *dst++ = 0;
  1024.  
  1025.  
  1026.  
  1027.  
  1028.  
  1029.     if(*string)    
  1030.      return string + 1;
  1031.     else 
  1032.      return 0;
  1033.     
  1034. }
  1035. dict_type *root;
  1036. dict_type *
  1037. DEFUN(lookup_word,(word),
  1038.       char *word)
  1039. {
  1040.   dict_type *ptr = root;
  1041.   while (ptr) {
  1042.       if (strcmp(ptr->word, word) == 0) return ptr;
  1043.       ptr = ptr->next;
  1044.         
  1045.     }
  1046.   if (warning)
  1047.    fprintf(stderr,"Can't find %s\n",word);
  1048.   return 0;
  1049.     
  1050.     
  1051. }
  1052.  
  1053. static void DEFUN_VOID(perform)
  1054. {
  1055.   tos = stack;
  1056.     
  1057.   while (at(ptr, idx)) {
  1058.       /* It's worth looking through the command list */
  1059.       if (iscommand(ptr, idx))
  1060.       {
  1061.     unsigned int i;
  1062.     int found = 0;
  1063.  
  1064.     char *next;
  1065.     dict_type *word ;
  1066.         
  1067.     (void)        nextword(addr(ptr, idx), &next);
  1068.  
  1069.  
  1070.     word = lookup_word(next);
  1071.  
  1072.  
  1073.         
  1074.  
  1075.     if (word) 
  1076.     {
  1077.       exec(word);
  1078.     }
  1079.     else
  1080.     {
  1081.       if (warning)
  1082.        fprintf(stderr,"warning, %s is not recognised\n",  next);
  1083.       skip_past_newline();
  1084.     }
  1085.         
  1086.       }
  1087.       else skip_past_newline();
  1088.  
  1089.     }
  1090. }
  1091.  
  1092. dict_type *
  1093. DEFUN(newentry,(word),
  1094.       char *word)
  1095. {
  1096.     dict_type *new = (dict_type *)malloc(sizeof(dict_type));
  1097.     new->word = word;
  1098.     new->next = root;
  1099.     root = new;
  1100.     new->code = (stinst_type *)malloc(sizeof(stinst_type ));
  1101.     new->code_length = 1;
  1102.     new->code_end = 0;
  1103.     return new;
  1104.     
  1105. }
  1106.  
  1107.  
  1108. unsigned int
  1109. DEFUN(add_to_definition,(entry, word), 
  1110.       dict_type *entry AND
  1111.       stinst_type word)
  1112. {
  1113.     if (entry->code_end == entry->code_length) 
  1114.     {
  1115.     entry->code_length += 2;
  1116.     entry->code =
  1117.      (stinst_type *) realloc((char *)(entry->code),
  1118.                    entry->code_length *sizeof(word_type));
  1119.     }
  1120.     entry->code[entry->code_end] = word;
  1121.     
  1122. return     entry->code_end++;  
  1123. }
  1124.  
  1125.  
  1126.  
  1127.  
  1128.  
  1129.  
  1130.  
  1131. void
  1132. DEFUN(add_intrinsic,(name, func),
  1133.       char *name AND
  1134.       void (*func)())
  1135. {
  1136.     dict_type *new = newentry(name);
  1137.     add_to_definition(new, func);
  1138.     add_to_definition(new, 0);
  1139. }
  1140.  
  1141. WORD(push_addr)
  1142. {
  1143.     
  1144.  
  1145. }
  1146.  
  1147. void
  1148. DEFUN(add_var,(name),
  1149.       char *name)
  1150. {
  1151.     dict_type *new = newentry(name);
  1152.     add_to_definition(new, push_number);
  1153.     add_to_definition(new, (stinst_type)(&(new->var)));
  1154.     add_to_definition(new,0);
  1155.     
  1156. }
  1157.       
  1158.  
  1159.  
  1160.  
  1161. void 
  1162. DEFUN(compile, (string), 
  1163.       char *string)
  1164.  
  1165. {
  1166.     int jstack[STACK];
  1167.     int *jptr = jstack;
  1168.     /* add words to the dictionary */
  1169.     char *word;
  1170.     string = nextword(string, &word);
  1171.     while (string && *string && word[0]) 
  1172.     {
  1173.     if (strcmp(word,"var")==0) 
  1174.     {
  1175.  string=nextword(string, &word);
  1176.       
  1177.       add_var(word);
  1178.  string=nextword(string, &word);
  1179.     }
  1180. else    
  1181.         
  1182.     if (word[0] == ':')
  1183.     {
  1184.         dict_type *ptr;
  1185.         /* Compile a word and add to dictionary */
  1186.         string = nextword(string, &word);
  1187.         
  1188.         ptr = newentry(word);
  1189.         string = nextword(string, &word);
  1190.         while (word[0] != ';' ) 
  1191.         {
  1192.          switch (word[0]) 
  1193.          {
  1194.             
  1195.             
  1196.            case '"':
  1197.              /* got a string, embed magic push string
  1198.             function */
  1199.              add_to_definition(ptr, push_text);
  1200.              add_to_definition(ptr, (stinst_type)(word+1));
  1201.              break;
  1202.            case '0':
  1203.            case '1':
  1204.            case '2':
  1205.            case '3':
  1206.            case '4':
  1207.            case '5':
  1208.            case '6':
  1209.            case '7':
  1210.            case '8':
  1211.            case '9':
  1212.              /* Got a number, embedd the magic push number
  1213.             function */
  1214.              add_to_definition(ptr, push_number);
  1215.              add_to_definition(ptr, atol(word));
  1216.              break;
  1217.            default:
  1218.              add_to_definition(ptr, call);
  1219.              add_to_definition(ptr, lookup_word(word));
  1220.          }
  1221.  
  1222.         string = nextword(string, &word);             
  1223.         }
  1224.         add_to_definition(ptr,0);
  1225.         string = nextword(string, &word);
  1226.     }
  1227.     else 
  1228.     {
  1229.         fprintf(stderr,"syntax error at %s\n",string-1);
  1230.     }        
  1231.     }
  1232.  
  1233. }
  1234.  
  1235.  
  1236. static void DEFUN_VOID(bang)
  1237. {
  1238. *(int *)((isp[0])) = isp[-1];
  1239. isp-=2;
  1240. pc++;
  1241.  
  1242. }
  1243.  
  1244. WORD(atsign)
  1245. {
  1246.     isp[0] = *(int *)(isp[0]);
  1247.     pc++;
  1248. }
  1249.  
  1250. WORD(hello)
  1251. {
  1252.     
  1253.     printf("hello\n");
  1254.     pc++;    
  1255. }
  1256.  
  1257.  
  1258.  
  1259. static void DEFUN(read_in, (str, file), 
  1260.        string_type *str AND
  1261.           FILE *file)
  1262. {
  1263.     char buff[10000];    
  1264.     unsigned int r;
  1265.     do 
  1266.     {
  1267.     r = fread(buff, 1, sizeof(buff), file);
  1268.     catbuf(str, buff, r);
  1269.     }
  1270.     while (r);
  1271.     buff[0] = 0;
  1272.     
  1273.     catbuf(str, buff,1);
  1274.     
  1275. }
  1276.  
  1277.  
  1278. static void DEFUN_VOID(usage)
  1279. {
  1280.     fprintf(stderr,"usage: -[d|i|g] <file >file\n");
  1281.     exit(33);    
  1282. }
  1283.  
  1284. int DEFUN(main,(ac,av),
  1285. int ac AND
  1286. char *av[])
  1287. {
  1288.   unsigned int i;
  1289.   string_type buffer;
  1290.   string_type pptr;
  1291.  
  1292.   init_string(&buffer);
  1293.   init_string(&pptr);
  1294.   init_string(stack+0);
  1295.   tos=stack+1;
  1296.   ptr = &pptr;
  1297.     
  1298.   add_intrinsic("push_text", push_text);
  1299.   add_intrinsic("!", bang);
  1300.   add_intrinsic("@", atsign);
  1301.   add_intrinsic("hello",hello);    
  1302.   add_intrinsic("skip_past_newline", skip_past_newline );
  1303.   add_intrinsic("catstr", icatstr );
  1304.   add_intrinsic("copy_past_newline", icopy_past_newline );
  1305.   add_intrinsic("dup", other_dup );
  1306.   add_intrinsic("remchar", remchar );
  1307.   add_intrinsic("get_stuff_in_command", get_stuff_in_command );
  1308.   add_intrinsic("do_fancy_stuff", do_fancy_stuff );
  1309.   add_intrinsic("bulletize", bulletize );
  1310.   add_intrinsic("courierize", courierize );
  1311.   /* If the following line gives an error, exit() is not declared in the
  1312.      ../hosts/foo.h file for this host.  Fix it there, not here!  */
  1313.   add_intrinsic("exit", exit );
  1314.   add_intrinsic("swap", swap );
  1315.   add_intrinsic("outputdots", outputdots );
  1316.   add_intrinsic("paramstuff", paramstuff );
  1317.   add_intrinsic("maybecatstr", maybecatstr );
  1318.   add_intrinsic("translatecomments", translatecomments );
  1319.   add_intrinsic("kill_bogus_lines", kill_bogus_lines);
  1320.   add_intrinsic("indent", indent);
  1321.   add_intrinsic("internalmode", internalmode);
  1322.     
  1323.   /* Put a nl at the start */
  1324.   catchar(&buffer,'\n');
  1325.  
  1326.   read_in(&buffer, stdin); 
  1327.   remove_noncomments(&buffer, ptr);
  1328.   for (i= 1; i < ac; i++) 
  1329.   {
  1330.     if (av[i][0] == '-')
  1331.     {
  1332.       if (av[i][1] == 'f')
  1333.       {
  1334.     string_type b;
  1335.     FILE *f;
  1336.     init_string(&b);
  1337.  
  1338.     f  = fopen(av[i+1],"r");
  1339.     if (!f) 
  1340.     {
  1341.       fprintf(stderr,"Can't open the input file %s\n",av[i+1]);
  1342.       return 33;
  1343.     }
  1344.         
  1345.           
  1346.     read_in(&b, f);
  1347.     compile(b.ptr);
  1348.     perform();    
  1349.       }
  1350.       else if (av[i][1] == 'i') 
  1351.       {
  1352.     internal_wanted = 1;
  1353.       }
  1354.       else if (av[i][1] == 'w') 
  1355.       {
  1356.     warning = 1;
  1357.       }
  1358.     }
  1359.  
  1360.   }      
  1361.   write_buffer(stack+0);
  1362.   return 0;
  1363. }
  1364.